package com.treasure.service.wechat.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.treasure.service.annotation.LogInfo;
import com.treasure.service.annotation.NoLogin;
import com.treasure.service.commons.lang.util.BeanUtil;
import com.treasure.service.commons.lang.util.IdCreater;
import com.treasure.service.commons.lang.util.StringUtil;
import com.treasure.service.constant.GlobalConstant;
import com.treasure.service.domain.AccessToken;
import com.treasure.service.dto.TUserInfoDto;
import com.treasure.service.enums.CodeEnum;
import com.treasure.service.enums.RedisKeys;
import com.treasure.service.result.ResponseResult;
import com.treasure.service.user.service.UserService;
import com.treasure.service.third.utils.CookiesUtil;
import com.treasure.service.third.utils.Sign;
import com.treasure.service.third.utils.TokenConfig;
import com.treasure.service.third.utils.UserToken;
import com.treasure.service.wechat.common.WxUser;
import com.treasure.service.wechat.dto.SyntonyMessage;
import com.treasure.service.wechat.service.WechatService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

/**
 * @author <a href="mailto:125671254@qq.com">Pan Xinwen</a>panxinwen
 * @ClassName: WechatController
 * @Description: TODO(公众号交互相关)
 * @date 2018年5月29日 下午21:47:59
 */
@RestController
public class WechatController {
    private Logger log = LoggerFactory.getLogger(WechatController.class);
    @Autowired
    private WechatService wechatService;

    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Value("${treasure.wx.appId}")
    private String appId;

    /**
     * 初始化 AccessToken
     * @param
     * @throws NoSuchAlgorithmException
     */
    @NoLogin
    @RequestMapping(value = "/updateAccess_token", method = RequestMethod.POST)
    public void updateAccessToken(){

        wechatService.updateAccess_token();

    }

    /**
     * 验证微信服务器
     *
     * @param
     * @param signature
     * @param timestamp
     * @param nonce
     * @param echostr
     * @throws NoSuchAlgorithmException
     */
    @NoLogin
    @RequestMapping(value = "/wechat", method = RequestMethod.GET)
    public String wechatService(
        @RequestParam(value = "signature", required = false) String signature, @RequestParam String timestamp,
        @RequestParam String nonce, @RequestParam String echostr) throws NoSuchAlgorithmException {
        return wechatService.wxListener(signature, timestamp, nonce, echostr);
    }

    /**
     * 接收来自微信发来的消息
     *
     * @param out
     * @param request
     * @param response
     */
    @NoLogin
    @ResponseBody
    @RequestMapping(value = "/wechat", method = RequestMethod.POST)
    public void wechatServicePost(PrintWriter out, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        String responseMessage = wechatService.processRequest(request);
        out.print(responseMessage);
        out.flush();
        out.close();
    }


    /**
     * 获取js sdk 认证信息
     *
     * @param
     * @return
     * @author
     */
    @SuppressWarnings("rawtypes")
    @LogInfo(log = "jssdk分享认证")
    @NoLogin
    @ApiOperation(value = "jssdk分享认证", notes = "v1")
    @ApiImplicitParams({
        @ApiImplicitParam(paramType = "query", dataType = "String", name = "url", value = "待签名url", required = true)
    })
    @RequestMapping(value = "/getSign", method = {RequestMethod.GET, RequestMethod.POST})
    public String getSign(@RequestParam(value = "url", required = true) String url) throws UnsupportedEncodingException {
        url = URLDecoder.decode(url, GlobalConstant.ENCODING_UTF8);
        log.info("校验签名的url============" + url);
        //获取ticket
        AccessToken accessToken = wechatService.getAccess_token();
        Map<String, String> ret = Sign.sign(accessToken.getJsapiTicket(), url);
        log.info("计算出的签名：" + ret.toString());
        JSONObject json = new JSONObject();
        for (Map.Entry entry : ret.entrySet()) {
            log.info((entry.getKey() + "=============" + entry.getValue()));
            json.put(entry.getKey().toString(), entry.getValue());
        }

        log.info("分享出去的url====" + url);

        json.put("shareUrl", url);
        json.put("appId", appId);

        return json.toString();
    }

    // 微信授权回调地址
    @NoLogin
    @RequestMapping(value = "/redirect", method = {RequestMethod.GET, RequestMethod.POST})
    @LogInfo(log = "微信授权登录")
    public void redirect(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        WxUser wxUser = wechatService.redirect(request);
        String opendId = wxUser.getOpenid();
        String access_token = wxUser.getAccess_token();
        log.info("获取用户基本信息：" + JSON.toJSONString(wxUser));

        wxUser = wechatService.wxUserInfo(opendId, access_token);

        log.info("从微信获取的用户信息:{}",JSON.toJSONString(wxUser));

        //查询是否存在该用户
        TUserInfoDto user = userService.getUserInfoByUnionid(wxUser.getUnionid());

        UserToken token =null;
        SyntonyMessage syntonyMessage = JSONObject.parseObject((String) redisTemplate.opsForHash().get(RedisKeys.REDIRECT_LIST.build(""), request.getParameter("state")),SyntonyMessage.class);
        redisTemplate.opsForHash().delete(RedisKeys.REDIRECT_LIST.build(""), request.getParameter("state"));
        log.info("授权通过获取缓存信息：" + JSON.toJSONString(syntonyMessage));
        if (user == null|| StringUtil.isEmpty(user.getUserId())) {
            log.info("获取用户微信信息：" + JSON.toJSONString(wxUser));
            //创建新用户
            user = new TUserInfoDto();
            user.setOpenId(opendId);
            user.setUnionid(wxUser.getUnionid());
            user.setNickname(wxUser.getNickname());
            user.setWNickname(wxUser.getNickname());
            user.setHeadimgurl(wxUser.getHeadimgurl());
            user.setWHeadimgurl(wxUser.getHeadimgurl());
            user.setInviteCode(StringUtil.isEmpty(syntonyMessage.getInviteCode())?"":syntonyMessage.getInviteCode());
            user = userService.createWechatUser(user);
            log.info("创建用户息：" + JSON.toJSONString(user));
            token = BeanUtil.copy(user, UserToken::new);
        } else {
            Long userId = user.getUserId();
            user = new TUserInfoDto();
            user.setUserId(userId);
            user.setWNickname(wxUser.getNickname());
            user.setWHeadimgurl(wxUser.getHeadimgurl());
            user =userService.updateUserInfo(user);
            log.info("更新用户：" + JSON.toJSONString(user));
            token = BeanUtil.copy(user, UserToken::new);
        }

        UserToken userToken = TokenConfig.addToken(token);

//        String h5 = request.getParameter("state");
//
//        Object redirecth5 = "" + redisTemplate.opsForHash().get(RedisKeys.REDIRECT_LIST.build(":REDIRECT_LIST"), h5) + "";
        Object redirecth5 = syntonyMessage.getRedirectUri();

        log.info("转发的地址===========" + redirecth5);

        CookiesUtil.setCookie(response,"token",userToken.getTokenId()+"",3600);

        try {
            response.sendRedirect(redirecth5+"");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }


    //微信授权
    @NoLogin
    @LogInfo(log = "授权登陆")
    @ApiOperation(value = "授权登陆", notes = "v1")
    @ApiImplicitParams({
        @ApiImplicitParam(paramType = "query", dataType = "String", name = "redirect_uri", value = "授权回调地址", required = true),
        @ApiImplicitParam(paramType = "query", dataType = "String", name = "redirect_code", value = "授权回调地址编号", required = true),
    })
    @RequestMapping(value = "/snsapibase", method = {RequestMethod.GET, RequestMethod.POST})
    public void snsapibase(
        @RequestParam(value = "redirect_uri", required = true) String redirect_uri,
        @RequestParam(value = "redirect_code", required = false) String redirect_code,
        @RequestParam(value = "inviteCode", required = false) String inviteCode,
        HttpServletResponse response) throws UnsupportedEncodingException {
        redirect_uri=URLDecoder.decode(redirect_uri, GlobalConstant.ENCODING_UTF8);

        SyntonyMessage syntonyMessage = new SyntonyMessage();
        if (StringUtil.isNotEmpty(inviteCode)){
            syntonyMessage.setInviteCode(inviteCode);
        }

        redirect_code = IdCreater.getLongId()+"";

        syntonyMessage.setRedirectUri(redirect_uri);
        log.info("授权登陆，缓存信息{}，urlcode{}", JSON.toJSONString(syntonyMessage), redirect_code);

        redisTemplate.opsForHash().put(RedisKeys.REDIRECT_LIST.build(), redirect_code, JSON.toJSONString(syntonyMessage));

        wechatService.snsapibase(redirect_uri, redirect_code, response);

    }

    //微信授权
    @NoLogin
    @LogInfo(log = "获取二维码")
    @ApiOperation(value = "生成用户推广二维码", notes = "v1")
    @PostMapping(value = "/getQRCode")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "Integer", name = "type", value = "分享图片地址", required = true),
    })
    public ResponseEntity getQRCode(@RequestParam(value = "type", required = true) Integer type){

//        UserToken userToken = TokenConfig.getTokenByHeader();

        String QRCode = wechatService.createShareImg(type,"10000001");

        return ResponseEntity.ok(new ResponseResult(CodeEnum.SUCCESS,QRCode));
    }




}
